#!/usr/bin/python
#
# Copyright 2011 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""GIT callback action class

Defines the actions for the callback page.
"""

__author__ = 'Xin Zhou(zhounew@google.com)'

from git.data import git_account
from git.util import git_context

class GitCallbackLogic:
  PURPOSE_SIGNIN = 'signin'
  PURPOSE_UPGRADE = 'upgrade'
  
  def __init__(self, callback_action):
    self.callback_action_ = callback_action
  
  def MergeAccountInfo(self, account, assertion):
    '''Merges the account properties in the assertion to the account. So
       that if the RP doesn't store
    '''
    if not account or not assertion:
      return
    if account.GetDisplayName() == '':
      account.SetDisplayName('%s %s' % (assertion.GetFirstName(),
                                        assertion.GetLastName()))
    if assertion.GetPhotoUrl() != '' and account.GetPhotoUrl() == '':
      account.SetPhotoUrl(assertion.GetPhotoUrl())
      
  def Run(self, request, response):
    purpose = request.GetPurpose();
    if (purpose != '' and purpose != GitCallbackLogic.PURPOSE_SIGNIN and
        purpose != GitCallbackLogic.PURPOSE_UPGRADE):
      response.SetError('Invalid param rp_purpose.')
    input_email = request.GetInputEmail()
    assertion = request.GetAssertion()
    if not assertion:
      self.callback_action_.SendErrorInvalidAssertion(request, response)
      return
    verified_email = assertion.GetVerifiedEmail()
    if not verified_email:
      self.callback_action_.SendErrorInvalidAssertionEmail(request, response)
      return
    request.SetInputEmail(verified_email)
    service = git_context.GitContext.GetAccountService()
    session_manager = git_context.GitContext.GetSessionManager()
    if purpose == '' or purpose == GitCallbackLogic.PURPOSE_SIGNIN:
      # Check whether the user input email matches the email in the IDP
      # assertion.
      if input_email != '' and input_email != verified_email:
        self.callback_action_.SaveAssertion(request, response)
        self.callback_action_.SendErrorMismatch(request, response)
      else:
        # Check whether the email already exists.
        account = service.GetAccountByEmail(verified_email)
        self.MergeAccountInfo(account, assertion)
        request.SetAccount(account)
        if account:
          if account.GetAccountType() != git_account.GitAccount.FEDERATED:
            self.callback_action_.Upgrade(request, response)
            account.SetAccountType(git_account.GitAccount.FEDERATED)
            request.SetAccount(account)
          self.callback_action_.Login(request, response)
          self.callback_action_.ShowHomePage(request, response)
        else:
          self.callback_action_.SaveAssertion(request, response)
          self.callback_action_.ShowNewAccountPage(request, response)
    elif purpose == GitCallbackLogic.PURPOSE_UPGRADE:
      account = session_manager.GetSessionAccount()
      if not account:
        response.SetError('The email %s has not logged in!' % (verified_email))
      elif account.GetEmail() != verified_email:
        self.callback_action_.SendErrorMismatch(request, response)
      else:
        self.callback_action_.Upgrade(request, response)
        self.callback_action_.SetFederatedTab(request, response)
        self.callback_action_.ShowHomePage(request, response)